#include "CvVision.h"

//CONSTRUCTOR & DESTRUCTOR
CvVision::CvVision()
{
	mCaptureType	= NO_CAPTURE;
	mWidth			= 0;
	mHeight			= 0;
	mFPS			= 0;
	mNumFrames		= 0;
	mPosFrames		= -1;
	mPath			= "";
	mImageColor		= BGR_IMAGE;
	mSamplingFactor = 1; 
}

CvVision::~CvVision()
{
	if(mLoad)
	{
		delete [] mImage.data;
		//cvReleaseImage(&mImage );
	}
}

//Camera tools
bool CvVision::captureCam()
{
	mCapture.open(CV_CAP_ANY);
	if( !mCapture.isOpened() ) 
		return false;
	mCaptureType = CAPTURE_FROM_CAM;
	mHeight =	(int)mCapture.get(CV_CAP_PROP_FRAME_HEIGHT);
	mWidth	=	(int)mCapture.get(CV_CAP_PROP_FRAME_WIDTH);
	
	//???
	mFPS = (int)mCapture.get(CV_CAP_PROP_FPS);
	
	return grabImage();
}

bool CvVision::grabImage(short int inImageColor)
{
	if(mCaptureType != CAPTURE_FROM_CAM)
		return false;
	mCapture>>mImage;		// retrieve the captured frame
	mLoad=false;
	if(inImageColor == USE_DEFAULT)
		inImageColor = mImageColor;
	switch(inImageColor)
	{
		case BGR_IMAGE:	break;
		case RGB_IMAGE: convertingBGR_RGB(); break;
		case HSV_IMAGE: convertingBGR_HSV(); break;
		default : return false;
	}
	return true;
}

//Video tools
bool CvVision::captureAVI(std::string inPath)
{
	//**Initializing capture from a file:**//
	mCapture.open(inPath.c_str());
	if(!mCapture.isOpened())
		return false;
	mPath=inPath;
	mCaptureType = CAPTURE_FROM_AVI;
	mCapture.set(CV_CAP_PROP_POS_FRAMES, 0.0);
	//**Get video information**//
	mHeight		= (unsigned int) mCapture.get(CV_CAP_PROP_FRAME_HEIGHT);
	mWidth		= (unsigned int) mCapture.get(CV_CAP_PROP_FRAME_WIDTH);
	mFPS		= (unsigned int) mCapture.get(CV_CAP_PROP_FPS);
	mNumFrames	= (unsigned int) mCapture.get(CV_CAP_PROP_FRAME_COUNT);
	return retrieveImage(0);
}

bool CvVision::retrieveImage(int inFrame,short int inImageColor,bool inOptimize)
{
	if(mPosFrames==inFrame && inOptimize)
		return true;
	if(mCaptureType != CAPTURE_FROM_AVI)
		return false;
	//**Retrieve a frame:**//
	if(inFrame > mNumFrames || inFrame < 0)			//Just to be sure
		return false;
	//if(mPosFrames!=inFrame)							//If the same frame is uptaded 2 times, it cause some sort of flip and color problem
	//{
		mPosFrames = inFrame;
		mCapture.set(CV_CAP_PROP_POS_FRAMES, (double)inFrame);	
		mCapture>>mImage;								// retrieve the captured frame
		mLoad = false;
		if(inImageColor == USE_DEFAULT)
			inImageColor = mImageColor;
		switch(inImageColor)
		{
			case BGR_IMAGE:	break;
			case RGB_IMAGE: convertingBGR_RGB(); break;
			case HSV_IMAGE: convertingBGR_HSV(); break;
			default : return false;
		}	
		//flipImage(mImage);							//Weirdly, the frame is reverse. We've got to flip it.
	//}
	return true;
}

//Load Image
bool CvVision::grabImage(char* inDataImage, int inWidth, int inHeight, int inChannels, int inType)
{
	if(inDataImage==NULL)
		return false;
	if(mLoad)
	{
		delete [] mImage.data;
		//cvReleaseImage(&mImage);
	}
	mLoad=true;
	mImage = cv::Mat(inWidth,inHeight,CV_MAKETYPE(inType,inChannels),inDataImage);
	mHeight=inHeight;
	mWidth=inWidth;
	return true;
}

//OpenCv Processing tools
void CvVision::convertingRGB_BGR()
{
	cvtColor(mImage, mImage, CV_RGB2BGR );
}
void CvVision::convertingBGR_RGB()
{
	cvtColor(mImage, mImage, CV_BGR2RGB );
}
void CvVision::convertingBGR_HSV()
{
	cvtColor(mImage, mImage, CV_BGR2HSV );
}

void CvVision::convertingHSV_BGR()
{	
	cvtColor(mImage, mImage, CV_HSV2BGR );
}

void CvVision::flipImage(short int inStyle)
{
	flip(mImage, mImage, inStyle); 
}

void CvVision::changeSize(short int inFactor)
{
	resize(mImage,mImage,cv::Size(),inFactor,inFactor,cv::INTER_CUBIC);
}

//Debugging tools
void CvVision::saveImage(std::string inImageName)
{
	if (mImage.cols > 0 && mImage.rows > 0 )
		cv::imwrite(inImageName.c_str(),mImage);
}

void CvVision::show()
{
	bool lShow = true;
	cv::namedWindow("mImage",CV_WINDOW_AUTOSIZE);
	while(lShow)
	{
		cv::imshow( "mImage", mImage );

		//If ESC key pressed
		if( (cvWaitKey(10) & 255) == 27 ) lShow=false;
	}
	cv::destroyWindow( "mImage" );
}

void CvVision::showStream()
{
	bool lShow = true;
	cv::namedWindow("LiveStream",CV_WINDOW_AUTOSIZE);
	while(lShow)
	{
	    // Get one frame
		if(!grabImage()) break;

		cv::imshow( "LiveStream", mImage );

		//If ESC key pressed
		if( (cv::waitKey(10) & 255) == 27 ) lShow=false;
	}
	cv::destroyWindow( "LiveStream" );
}
